package cn.senjoeson.healthsport.pedometer;


import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

/**
 * Detects steps and notifies all listeners (that implement StepListener).
 *
 * @author Levente Bagi
 */
public class StepDetector implements SensorEventListener/*, SensorListener*/ {

    private float mLimit = 10;
    private float mLastValues[] = new float[3 * 2];
    private float mScale[] = new float[2];
    private float mYOffset;

    private float mLastDirections[] = new float[3 * 2];
    private float mLastExtremes[][] = {new float[3 * 2], new float[3 * 2]};
    private float mLastDiff[] = new float[3 * 2];
    private int mLastMatch = -1;

    private StepListener mListener;

    public StepDetector() {
        int h = 480;
        mYOffset = h * 0.5f;
        mScale[0] = -(h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
        mScale[1] = -(h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
    }

    public void setSensitivity(float sensitivity) {
        mLimit = sensitivity;
    }

    public void setStepListener(StepListener sl) {
        mListener = sl;
    }


    // 给传感器添加侦听器
    public double magnitude(float x, float y, float z) {
        // 向量求模函数
        double magnitude = 0;
        magnitude = Math.sqrt(x * x + y * y + z * z);
        return magnitude;

    }

    @SuppressWarnings("deprecation")
    public void onSensorChanged(SensorEvent event) {
        Sensor sensor = event.sensor;
        synchronized (this) {
            if (sensor.getType() == Sensor.TYPE_ORIENTATION) {


            } else {
                int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0;
                if (j == 1) {
                    float vSum = 0;
                    for (int i = 0; i < 3; i++) {
                        final float v = mYOffset + event.values[i] * mScale[j];
                        vSum += v;
                    }
                    int k = 0;
                    float v = vSum / 3;

                    float direction = (v > mLastValues[k] ? 1 : (v < mLastValues[k] ? -1 : 0));
                    if (direction == -mLastDirections[k]) {

                        int extType = (direction > 0 ? 0 : 1);
                        mLastExtremes[extType][k] = mLastValues[k];
                        float diff = Math.abs(mLastExtremes[extType][k] - mLastExtremes[1 - extType][k]);

                        if (diff > mLimit) {

                            boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k] * 2 / 3);
                            boolean isPreviousLargeEnough = mLastDiff[k] > (diff / 3);
                            boolean isNotContra = (mLastMatch != 1 - extType);

                            if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) {
                                if (mListener != null) {
                                    mListener.onStep();
                                }
                                mLastMatch = extType;
                            } else {
                                mLastMatch = -1;
                            }
                        }
                        mLastDiff[k] = diff;
                    }
                    mLastDirections[k] = direction;
                    mLastValues[k] = v;
                }
            }
        }
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    private double _oriValue; // 原始数
    private double _lstValue; // 上次数
    private double _curValue; // 当前数
    private boolean _motiveState = true; // 运动状态

    /*@Override
    public void onSensorChanged(int sensor, float[] values) {
        if (sensor == Sensor.TYPE_ORIENTATION) {
// 设定一个精度范围,测试验证发现修改精度值影响模拟的效果，即前后手机的幅度、速度之类的会影响记步的效果
            double range = 2;
            // 计算当前加速向量的模
            _curValue = magnitude(values[0], values[1], values[2]);
            // 向上加速状态
            if (_motiveState == true) {
                if (_curValue >= _lstValue) {
                    _lstValue = _curValue;
                } else {
                    if (Math.abs(_curValue - _lstValue) > range) { // 检测到一次峰值
                        _oriValue = _curValue;
                        _motiveState = false;
                    }
                }
            }
        }
    }

    @Override
    public void onAccuracyChanged(int sensor, int accuracy) {

    }*/
}